package com.mmall.service;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.mmall.dao.SysAclMapper;
import com.mmall.dao.SysAclModuleMapper;
import com.mmall.dao.SysDeptMapper;
import com.mmall.dto.AclDto;
import com.mmall.dto.AclModuleLevelDto;
import com.mmall.dto.DeptLevelDto;
import com.mmall.model.SysAcl;
import com.mmall.model.SysAclModule;
import com.mmall.model.SysDept;
import com.mmall.util.LevelUtil;
import org.apache.commons.collections.CollectionUtils;
import com.google.common.collect.Multimap;
import org.apache.commons.collections.MultiMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Auther 19135
 * @Date 2019/1/1 17:28
 * @Description 树service
 */
@Service
public class SysTreeService {

	@Resource
	private SysDeptMapper sysDeptMapper;

	@Resource
	private SysAclModuleMapper sysAclModuleMapper;

	@Resource
	private SysCoreService sysCoreService;

	@Resource
	private SysAclMapper sysAclMapper;

	public List<AclModuleLevelDto> userAclTree(int userId){
		//获取用户拥有的所有权限
		List<SysAcl> userAclList = sysCoreService.getUserAclList(userId);
		ArrayList<AclDto> aclDtoList = Lists.newArrayList();
		for (SysAcl acl : userAclList) {
			AclDto dto = AclDto.adapt(acl);
			dto.setHasAcl(true);
			dto.setChecked(true);
			aclDtoList.add(dto);
		}
		return  aclListToTree(aclDtoList);
	}

	//获得该角色所拥有的权限模块
	public List<AclModuleLevelDto> roleTree(int roleId) {
		// 1、当前用户已分配的权限点
		List<SysAcl> userAclList = sysCoreService.getCurrentUserAclList();
		//2、当前角色分配的权限点
		List<SysAcl> roleAclList = sysCoreService.getRoleAclList(roleId);
		//3、当前系统所有权限点
		List<AclDto> aclDtoList = Lists.newArrayList();

		Set<Integer> userAclIdSet = userAclList.stream().map(sysAcl -> sysAcl.getId()).collect(Collectors.toSet());
		Set<Integer> roleAclIdSet = roleAclList.stream().map(sysAcl -> sysAcl.getId()).collect(Collectors.toSet());

		List<SysAcl> allAclList = sysAclMapper.getAll();
		for (SysAcl acl : allAclList) {
			AclDto dto = AclDto.adapt(acl);
			if (userAclIdSet.contains(acl.getId())) {
				dto.setHasAcl(true);
			}
			if (roleAclIdSet.contains(acl.getId())) {
				dto.setChecked(true);
			}
			aclDtoList.add(dto);
		}
		return aclListToTree(aclDtoList);
	}


	//将权限集合转换为权限模型树形结构
	public List<AclModuleLevelDto> aclListToTree(List<AclDto> aclDtoList){
		if (CollectionUtils.isEmpty(aclDtoList)){
			return Lists.newArrayList();
		}
		//获得整个权限模块
		List<AclModuleLevelDto> aclModuleLevelList = aclModuleTree();

		ArrayListMultimap<Integer, AclDto> moduleIdAclMap = ArrayListMultimap.create();

		for (AclDto acl : aclDtoList) {
			//找到所有状态正常的权限
			if (acl.getStatus() == 1){
				moduleIdAclMap.put(acl.getAclModuleId(), acl);
			}
		}
		bindAclsWithOrder(aclModuleLevelList, moduleIdAclMap);
		return aclModuleLevelList;
	}


	public void bindAclsWithOrder(List<AclModuleLevelDto> aclModuleLevelList, Multimap<Integer, AclDto> moduleIdAclMap) {
		if (CollectionUtils.isEmpty(aclModuleLevelList)) {
			return;
		}
		for (AclModuleLevelDto dto : aclModuleLevelList) {
			List<AclDto> aclDtoList = (List<AclDto>)moduleIdAclMap.get(dto.getId());
			if (CollectionUtils.isNotEmpty(aclDtoList)) {
				Collections.sort(aclDtoList, aclSeqComparator);
				dto.setAclList(aclDtoList);
			}
			bindAclsWithOrder(dto.getAclModuleList(), moduleIdAclMap);
		}
	}

	public List<AclModuleLevelDto> aclModuleTree(){
		//获取所有的权限模块集合
		List<SysAclModule> aclModuleList = sysAclModuleMapper.getAllAclModule();
		List<AclModuleLevelDto> dtoList = Lists.newArrayList();
		//转化为dto对象
		for (SysAclModule aclModule : aclModuleList) {
			dtoList.add(AclModuleLevelDto.adapt(aclModule));
		}
		return aclModuleListToTree(dtoList);
	}

	//转换成树形结构
	public List<AclModuleLevelDto> aclModuleListToTree(List<AclModuleLevelDto> dtoList){
		if (CollectionUtils.isEmpty(dtoList)){
			return Lists.newArrayList();
		}
		Multimap<String, AclModuleLevelDto> levelAclModuleMap = ArrayListMultimap.create();
		List<AclModuleLevelDto> rootList = Lists.newArrayList();

		for (AclModuleLevelDto dto : dtoList) {
			levelAclModuleMap.put(dto.getLevel(), dto);
			if (LevelUtil.ROOT.equals(dto.getLevel())){
				rootList.add(dto);
			}
		}
		//对该层级进行排序
		Collections.sort(rootList,aclModuleSeqComparator);
		transformAclModuleTree(rootList, LevelUtil.ROOT, levelAclModuleMap);
		return rootList;
	}

	public void transformAclModuleTree(List<AclModuleLevelDto> dtoList, String level, Multimap<String, AclModuleLevelDto> levelAclModuleMap) {
		for (int i = 0; i < dtoList.size(); i++) {
			AclModuleLevelDto dto = dtoList.get(i);
			//得到子模块的level标识
			String nextLevel = LevelUtil.calculateLevel(level, dto.getId());
			//取出该层所有的模块
			List<AclModuleLevelDto> tempList = (List<AclModuleLevelDto>) levelAclModuleMap.get(nextLevel);
			if (CollectionUtils.isNotEmpty(tempList))
				Collections.sort(tempList, aclModuleSeqComparator);
				dto.setAclModuleList(tempList);
				//去完善子模块的结构
				transformAclModuleTree(tempList, nextLevel, levelAclModuleMap);
		}
	}


	//获取当前部门tree
	public List<DeptLevelDto> deptTree(){
		//从数据库中获取所有的数据
		List<SysDept> deptList = sysDeptMapper.getAllDept();

		List<DeptLevelDto> dtoLIst = Lists.newArrayList();
		for (SysDept dept : deptList) {
			DeptLevelDto dto = DeptLevelDto.adapt(dept);
			dtoLIst.add(dto);
		}
		return deptListToTree(dtoLIst);
	}

	public List<DeptLevelDto> deptListToTree(List<DeptLevelDto> dtoList) {
		if (CollectionUtils.isEmpty(dtoList)){
			return Lists.newArrayList();
		}
		// level -> [dept1, dept2, ...] Map<String, List<Object>>
		Multimap<String,DeptLevelDto> levelDeptMap = ArrayListMultimap.create();
		List<DeptLevelDto> rootList = Lists.newArrayList();

		//先把 root 节点的全部构建好
		for (DeptLevelDto dto : dtoList) {
			levelDeptMap.put(dto.getLevel(),dto);
			if (LevelUtil.ROOT.equals(dto.getLevel())){
				rootList.add(dto);
			}
		}
		//按照seq从小到大排序
		Collections.sort(rootList,(o1,o2)-> o1.getSeq()-o2.getSeq() );

		//递归生成树
		transformDeptTree(rootList,LevelUtil.ROOT,levelDeptMap);
		return rootList;
	}

	public void transformDeptTree(List<DeptLevelDto> deptLevelList, String level, Multimap<String, DeptLevelDto> levelDeptMap) {
		for (DeptLevelDto dept : deptLevelList) {

			//取出当前要获取的层级  level
			String nextLevel = LevelUtil.calculateLevel(level,dept.getId());
			//获取该层级数据
			List<DeptLevelDto> tempDeptList = (List<DeptLevelDto> )levelDeptMap.get(nextLevel);
			if (CollectionUtils.isNotEmpty(tempDeptList)){
				//排序
				Collections.sort(tempDeptList,(o1,o2) -> o1.getSeq().compareTo(o2.getSeq()));

				//设置下一层部门
				dept.setDeptList(tempDeptList);
				//进入到下一层处理
				transformDeptTree(tempDeptList,nextLevel,levelDeptMap);
			}
		}

	}
	public Comparator<DeptLevelDto> deptSeqComparator = new Comparator<DeptLevelDto>() {
		public int compare(DeptLevelDto o1, DeptLevelDto o2) {
			return o1.getSeq() - o2.getSeq();
		}
	};

	public Comparator<AclModuleLevelDto> aclModuleSeqComparator = new Comparator<AclModuleLevelDto>() {
		public int compare(AclModuleLevelDto o1, AclModuleLevelDto o2) {
			return o1.getSeq() - o2.getSeq();
		}
	};
	public Comparator<AclDto> aclSeqComparator = new Comparator<AclDto>() {
		public int compare(AclDto o1, AclDto o2) {
			return o1.getSeq() - o2.getSeq();
		}
	};
}
